#include "airmouse.h"
#include "Windows.h"
AirMouse::AirMouse()
{
}

void AirMouse::onInit(const Controller& controller) {
circleduty = 1000000;
circlemax = 50;
modus = 0;
velovariable = 0.01;
normalvariable = 10;
basefactor = 0;
}

void AirMouse::onConnect(const Controller& controller) {
    controller.enableGesture(Gesture::TYPE_CIRCLE);
    controller.enableGesture(Gesture::TYPE_KEY_TAP);
    controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
    controller.enableGesture(Gesture::TYPE_SWIPE);

}

void AirMouse::onDisconnect(const Controller& controller) {

}

void AirMouse::onExit(const Controller& controller) {

}

void AirMouse::setModus(int i){
    modus = i;
}

void AirMouse::setnormalvariable(float i){
    normalvariable = i;
}

void AirMouse::setvelovariable(float i){
    velovariable = i/1000;
}

void AirMouse::setbasefactor(float i){
    basefactor = i/20;
}

float AirMouse::calculatebase(float i){
    if (abs(i)<basefactor){
        return 0;
    } else if (i < 0){
        return (i + basefactor);
    } else {
        return (i - basefactor);
    }

}

void AirMouse::onFrame(const Controller& controller) {

    const Frame frame = controller.frame();
    INPUT Input={0};
    Input.type = INPUT_MOUSE;
    const Hand hand = frame.hands()[0];

    if(modus == 0){
        if (!frame.hands().isEmpty()) {

            float normalx = hand.palmNormal().x; //flugzeug links positiv, rechts negativ
            float directiony = hand.direction().y; //flugzeug rauf positiv, runter negativ

            float velocityx = hand.palmVelocity().x;
            float velocityy = hand.palmVelocity().y;

            float nx = ((-normalvariable) * calculatebase(normalx)) + ((velovariable) * velocityx);
            float ny = ((-normalvariable) * calculatebase(directiony)) + ((-velovariable) * velocityy);

            Input.mi.dx = (LONG)nx;
            Input.mi.dy = (LONG)ny;

            // set move cursor directly and left click
            Input.mi.dwFlags = MOUSEEVENTF_MOVE;
        }
    }else if(modus==1){
        if (!frame.hands().isEmpty()) {

            float normalx = hand.palmNormal().x; //flugzeug links positiv, rechts negativ
            float directiony = hand.direction().y; //flugzeug rauf positiv, runter negativ

            float positionx = hand.palmPosition().x;
            float positiony = hand.palmPosition().y;

            static float oldpositionx = 0;
            static float oldpositiony = 0;

            float nx = ((-normalvariable) * calculatebase(normalx)) + ((velovariable) *(oldpositionx - positionx));
            float ny = ((-normalvariable) * calculatebase(directiony)) + (( velovariable) *(oldpositiony - positiony));

            oldpositionx = positionx;
            oldpositiony = positiony;

            Input.mi.dx = (LONG)nx;
            Input.mi.dy = (LONG)ny;

            // set move cursor directly and left click
            Input.mi.dwFlags = MOUSEEVENTF_MOVE;
        }
    }else if(modus==2){
        if (!frame.hands().isEmpty()) {

            float normalx = hand.palmNormal().x; //flugzeug links positiv, rechts negativ
            float directiony = hand.direction().y; //flugzeug rauf positiv, runter negativ

            float velocityx = hand.palmVelocity().x;
            float velocityy = hand.palmVelocity().y;

            float nx = ((-normalvariable) * normalx) + ((velovariable) * velocityx);
            float ny = ((-normalvariable) * directiony) + ((-velovariable) * velocityy);

            Input.mi.dx = (LONG)nx;
            Input.mi.dy = (LONG)ny;

            // set move cursor directly and left click
            Input.mi.dwFlags = MOUSEEVENTF_MOVE;
        }
    }

    // Get gestures

    const GestureList gestures = frame.gestures();

    static int circlei = 0;
    static int circlegewicht = 0;
    static int64_t oldframe = 0;
    static int64_t swipeduty = 100000;
    static int64_t oldswipe = 0;

    for (int g = 0; g < gestures.count(); ++g) {
        Gesture gesture = gestures[g];

        switch (gesture.type()) {

        case Gesture::TYPE_CIRCLE:
        {

            CircleGesture circle = gesture;

            if ((oldframe + circleduty) < frame.timestamp()){
                circlei = 0; circlegewicht = 0;
                oldframe = frame.timestamp();
            }


            if (circle.pointable().direction().angleTo(circle.normal()) <= PI/4) {
                circlegewicht++;circlei++;//std::cout << "l" << circlegewicht << circlei << std::endl;
            } else {
                circlei++;//std::cout << "r"<< circlegewicht << circlei << std::endl;
            }

            if (circlei==circlemax)
            {
                if(circlegewicht>(circlemax/2))
                {
                    Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;
                    oldframe = frame.timestamp();circlei = 0; circlegewicht = 0;
                }
                else
                {
                    Input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP;
                    oldframe = frame.timestamp();circlei = 0; circlegewicht = 0;
                }
            }
            break;
        }
        case Gesture::TYPE_SWIPE:
        {
            SwipeGesture swipe = gesture;

            if (frame.timestamp() > (oldswipe + swipeduty))
            {
                INPUT Input1={1};
                Input1.type = INPUT_KEYBOARD;
                if (swipe.direction().x < 0){
                    Input1.ki.wVk = VK_PRIOR;
                } else {
                    Input1.ki.wVk = VK_NEXT;
                }

                SendInput(1,&Input1,sizeof(INPUT));
                oldswipe = frame.timestamp();
            } else { oldswipe = frame.timestamp(); }
            break;
        }
        case Gesture::TYPE_KEY_TAP:
        {
            Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;
            break;
        }
        default:
            break;
        }
    }
    SendInput(1,&Input,sizeof(INPUT));
}

void AirMouse::onFocusGained(const Controller& controller) {

}

void AirMouse::onFocusLost(const Controller& controller) {

}
